#include "utility.h"
#include "Engine.h"
#include "display.h"
#include "glib.h"
#include <math.h>


int Utility::abs(int x)
{
	return x < 0 ? -x : x;
}

// convert color from ARGB 4444 format in a short to ARGB 8888 format in an int
int Utility::RGB4444to8888(short color)
{
	if (color == 0)
		return 0;
	else
		return (0xFF << 24)
		+ ((color & 0x0F00) << 12) + ((color & 0x0F00) << 8)
		+ ((color & 0x00F0) << 8) + ((color & 0x00F0) << 4)
		+ ((color & 0x000F) << 4) + (color & 0x000F);
}

int Utility::log2(int n)
{
	int mark, result;
	if (n >= 0x10000)
	{ result = 16; mark = 0x1000000; }
	else { result = 0;  mark = 0x100; }
	if (n >= mark) { result += 8; mark <<= 4; } else mark >>= 4;
	if (n >= mark) { result += 4; mark <<= 2; } else mark >>= 2;
	if (n >= mark) { result += 2; mark <<= 1; } else mark >>= 1;
	if (n >= mark) { result += 1; }
	return result;
}

int Utility::limit(int num, int min, int max)
{
	// optimiz those code :
	//
	//if (num > max)
	//    return max;
	//else if (num < min)
	//    return min;
	//else
	//    return num;
	return num > max ? max : ((num < min)? min: num);
}

//static int random(int min, int max)
//{
//	return 0;
//}

int Utility::fastDistance(int x, int y)
{
	if (x < 0) x = -x;
	if (y < 0) y = -y;
	int m = x>y ? y : x;
	return x + y - (m>>1) - (m>>2) + (m>>3);
}
int Utility::slowDistance(int dx, int dy)
{
	int min, max;

	if ( dx < 0 ) dx = -dx;
	if ( dy < 0 ) dy = -dy;

	if ( dx < dy )
	{
		min = dx;
		max = dy;
	} else {
		min = dy;
		max = dx;
	}

	// coefficients equivalent to ( 123/128 * max ) and ( 51/128 * min )
	return ((( max << 8 ) + ( max << 3 ) - ( max << 4 ) - ( max << 1 ) +
		( min << 7 ) - ( min << 5 ) + ( min << 3 ) - ( min << 1 )) >> 8 );
}

int Utility::verySlowDistance(int dx, int dy)
{
	if (dx < 0)
		dx = -dx;
	if (dy < 0)
		dy = -dy;

	return squareRoot((dx >> 8) * dx + (dy >> 8) * dy);
}
/**
* Cacualte square root for a positive integer with 8-bits floating point
* @param n int - Positive integer to be caculated with 8-bits floating point
* @return int - Positive integer with 8-bits floating point
*/
int Utility::squareRoot(int n)
{
	// sqrt(0) should = 0 not throw exception.
	if (n == 0)
		return 0;

	int x = n;
	int newx = 0;
	while (true)
	{
		newx = (x + n / x * 256) >> 1;
		if ((x >= newx ? x - newx : newx - x) < 256)
			break;
		x = newx;
	}
	return x;
}
//---------------------------------------------------------------------------
CMath::CMath()
{

}

CMath::~CMath()
{

}

void CMath::GetSinCos()
{
	for(int ang=0; ang<361; ang++)
	{
		float r = (float)ang*3.14159/180;
		mySin[ang] = sin(r);
		myCos[ang] = cos(r);
	}
}
